/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.gui.widgets.layouts;

import java.awt.geom.Point2D;

import org.jgrapht.DirectedGraph;

import dgbgui.gui.DefaultCanvasScene;
import dgbgui.gui.widgets.Widget;
import dgbgui.gui.widgets.visual.results.ResultWidget;
import dgbgui.modeldocument.primitives.DefaultEdgeWithWidget;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.util.PBounds;

@SuppressWarnings("serial")
public class FruchtermanReingoldLayout extends GraphLayout {


    public FruchtermanReingoldLayout(PNode parent, double margin, double spacing) {
        super(parent,margin,spacing); 
    }


    public void setGraph(DirectedGraph<Widget,DefaultEdgeWithWidget> graph) {
        super.setGraph(graph);
        
        // 5 seconds max
        DefaultCanvasScene.getInstance().getLayer().getRoot().addActivity(new FruchtermanReingoldLayoutActivity(this,15000,100));
    }


    public void layoutChildren() {


        // Move all the children to the top left corner
        double minXOffset = Double.MAX_VALUE;
        double minYOffset = Double.MAX_VALUE;
        
        // Calculate the minimun offset
        for ( int index = 0; index < getChildrenCount(); ++index ) {
            PNode child = getChild(index);
            if ( child instanceof ResultWidget ) {
                minXOffset = Math.min(child.getXOffset(), minXOffset);
                minYOffset = Math.min(child.getYOffset(), minYOffset);
            }
        }
        
        // Move to the upper left corner
        for ( int index = 0; index < getChildrenCount(); ++index ) {
            PNode child = getChild(index);
            Point2D currentOffset = child.getOffset();
            child.setOffset(new Point2D.Double(
                    currentOffset.getX() - minXOffset + m_margin,
                    currentOffset.getY() - minYOffset + m_margin));
        }

    }   
    

    
    public PBounds computeFullBounds(PBounds dstBounds) {
        PBounds result = getUnionOfChildrenBounds(dstBounds);
        result.setRect(0,0,result.getWidth() + 2*m_margin,result.getHeight() + 2*m_margin);
        localToParent(result);
        dstBounds.setRect(result);
        return result;      
    }


}

